home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 16
/
Aminet 16 (1996)(GTI - Schatztruhe)[!][Dec 1996].iso
/
Aminet
/
comm
/
term
/
term_source.lha
/
Extras
/
Source
/
term-source.lha
/
Transfer.c
< prev
next >
Wrap
C/C++ Source or Header
|
1996-10-20
|
46KB
|
2,206 lines
/*
** Transfer.c
**
** File transfer routines
**
** Copyright © 1990-1996 by Olaf `Olsen' Barthel
** All Rights Reserved
**
** :ts=4
*/
#ifndef _GLOBAL_H
#include "Global.h"
#endif
/* Prototypes for local routines. */
STATIC VOID CommonStartReceive(LONG Type, STRPTR Name, BOOL WaitForIt);
STATIC BOOL CommonStartSend(LONG Type, STRPTR TheFile, struct FileTransferInfo **TransferInfoPtr, BOOL WaitForIt);
STATIC BOOL SelectProtocol(struct Window *ParentWindow);
STATIC BOOL StartSend(BOOL IsBinary);
STATIC BOOL StartReceive(BOOL IsBinary);
STATIC VOID StripLibrary(STRPTR Protocol, STRPTR NameBuffer, LONG NameSize);
STATIC BOOL IsZModem(STRPTR String);
STATIC VOID CommonExternalSetup(STRPTR Buffer);
STATIC BOOL CommonXPRSetup(STRPTR ProtocolName, BOOL IgnoreOptions);
STATIC struct Node *CreateArgName(STRPTR String);
STATIC STRPTR BuildString(STRPTR Source, STRPTR From, STRPTR To, BYTE Type, BOOL ReceiveMode, STRPTR SingleFile, struct FileTransferInfo *Info, LONG *Error);
STATIC STRPTR ReplaceName(STRPTR Source);
STATIC VOID CommonStartSendXPR(LONG Type, BOOL IsBinary, BOOL WaitForIt);
STATIC VOID CommonSendXPRCleanup(BOOL WaitForIt);
STATIC VOID CommonStartReceiveXPR(LONG Type, BOOL IsBinary, BOOL WaitForIt);
STATIC LONG TransferCompare(struct FileTransferNode **A, struct FileTransferNode **B);
/* CommonStartReceive():
*
* Receive files via XPR or a different protocol.
*/
STATIC VOID
CommonStartReceive(LONG Type,STRPTR Name,BOOL WaitForIt)
{
STRPTR From,To,Cmd;
BOOL IsBinary;
LONG Mode;
if(Type == TRANSFER_ASCII && Config->TransferConfig->ASCIIDownloadType == XFER_INTERNAL)
{
InternalASCIIDownload(Name,WaitForIt);
return;
}
IsBinary = FALSE;
switch(Type)
{
case TRANSFER_BINARY:
Cmd = Config->TransferConfig->BinaryDownloadLibrary;
Mode = Config->TransferConfig->BinaryDownloadType;
From = Config->PathConfig->BinaryUploadPath;
To = Config->PathConfig->BinaryDownloadPath;
IsBinary = TRUE;
break;
case TRANSFER_TEXT:
Cmd = Config->TransferConfig->TextDownloadLibrary;
Mode = Config->TransferConfig->TextDownloadType;
From = Config->PathConfig->TextUploadPath;
To = Config->PathConfig->TextDownloadPath;
break;
case TRANSFER_ASCII:
Cmd = Config->TransferConfig->ASCIIDownloadLibrary;
Mode = Config->TransferConfig->ASCIIDownloadType;
From = Config->PathConfig->ASCIIUploadPath;
To = Config->PathConfig->ASCIIDownloadPath;
break;
}
if(Mode == XFER_DEFAULT && Config->TransferConfig->DefaultType == XFER_EXTERNALPROGRAM)
{
Cmd = Config->TransferConfig->DefaultLibrary;
Mode = XFER_EXTERNALPROGRAM;
}
if(Mode == XFER_EXTERNALPROGRAM)
{
STRPTR String;
LONG Error;
BlockWindows();
if(String = BuildString(Cmd,From,To,Type,TRUE,Name,NULL,&Error))
{
ClearSerial();
LaunchCommand(String);
RestartSerial();
FreeVecPooled(String);
}
ReleaseWindows();
}
else
{
struct FileRequester *FileRequest;
UBYTE DummyBuffer[MAX_FILENAME_LENGTH];
BPTR NewDir = NULL,
OldDir = NULL;
ClearGenericList(GenericListTable[GLIST_DOWNLOAD],FALSE);
/* Select the download path. */
switch(Type)
{
case TRANSFER_BINARY:
DownloadPath = Config->PathConfig->BinaryDownloadPath;
break;
case TRANSFER_TEXT:
DownloadPath = Config->PathConfig->TextDownloadPath;
break;
case TRANSFER_ASCII:
DownloadPath = Config->PathConfig->ASCIIDownloadPath;
break;
}
if(DownloadPath[0])
{
if(NewDir = Lock(DownloadPath,ACCESS_READ))
OldDir = CurrentDir(NewDir);
}
BlockWindows();
/* Set up the library if necessary. */
if(!XProtocolBase)
{
if(SelectProtocol(Window))
{
if(ProtocolSetup(FALSE))
SaveProtocolOpts();
}
}
if(XProtocolBase)
{
SetTransferMenu(TRUE);
/* Do we need to ask the user for
* the destination file name?
*/
if(TransferBits & XPRS_NORECREQ)
CommonStartReceiveXPR(Type,IsBinary,WaitForIt);
else
{
if(!Name)
{
LimitedStrcpy(sizeof(DummyBuffer),DummyBuffer,DownloadPath);
if(FileRequest = SaveFile(Window,LocaleString(MSG_TERMTRANSFER_DOWNLOAD_FILE_TXT + (Type - TRANSFER_BINARY)),LocaleString(MSG_TERMTRANSFER_RECEIVE_TXT),NULL,DummyBuffer,sizeof(DummyBuffer)))
{
FreeAslRequest(FileRequest);
/* Save the download path. */
strcpy(DownloadPath,DummyBuffer);
*PathPart(DownloadPath) = 0;
ConfigChanged = TRUE;
/* Install the name of the file to receive. */
XprIO->xpr_filename = DummyBuffer;
Name = DummyBuffer;
}
}
else
{
STRPTR Index;
strcpy(DownloadPath,Name);
ConfigChanged = TRUE;
Index = PathPart(DownloadPath);
*Index = 0;
XprIO->xpr_filename = Name;
}
/* Download the file(s). */
if(Name)
CommonStartReceiveXPR(Type,IsBinary,WaitForIt);
}
}
else
SetTransferMenu(TRUE);
if(NewDir)
UnLock(CurrentDir(OldDir));
if(SendAbort)
{
CancelZModem();
SendAbort = FALSE;
}
ReleaseWindows();
DownloadPath = NULL;
DidTransfer = FALSE;
if(WaitForIt)
{
if(Config->CommandConfig->DownloadMacro[0])
SerialCommand(Config->CommandConfig->DownloadMacro);
}
}
}
/* CommonStartSend():
*
* Send files via XPR or a different protocol.
*/
STATIC BOOL
CommonStartSend(LONG Type,STRPTR TheFile,struct FileTransferInfo **TransferInfoPtr,BOOL WaitForIt)
{
STRPTR From,To,Name;
BOOL IsBinary;
LONG Mode;
if(TheFile)
TheFile = ReplaceName(TheFile);
if(Type == TRANSFER_ASCII && Config->TransferConfig->ASCIIDownloadType == XFER_INTERNAL)
return(InternalASCIIUpload(TheFile,WaitForIt));
IsBinary = FALSE;
switch(Type)
{
case TRANSFER_BINARY:
Name = Config->TransferConfig->BinaryUploadLibrary;
Mode = Config->TransferConfig->BinaryUploadType;
From = Config->PathConfig->BinaryUploadPath;
To = Config->PathConfig->BinaryDownloadPath;
IsBinary = TRUE;
break;
case TRANSFER_TEXT:
Name = Config->TransferConfig->TextUploadLibrary;
Mode = Config->TransferConfig->TextUploadType;
From = Config->PathConfig->TextUploadPath;
To = Config->PathConfig->TextDownloadPath;
break;
case TRANSFER_ASCII:
Name = Config->TransferConfig->ASCIIUploadLibrary;
Mode = Config->TransferConfig->ASCIIUploadType;
From = Config->PathConfig->ASCIIUploadPath;
To = Config->PathConfig->ASCIIDownloadPath;
break;
}
if(Mode == XFER_DEFAULT && Config->TransferConfig->DefaultType == XFER_EXTERNALPROGRAM)
{
Name = Config->TransferConfig->DefaultLibrary;
Mode = XFER_EXTERNALPROGRAM;
}
if(Mode == XFER_EXTERNALPROGRAM)
{
STRPTR String;
LONG Error;
BOOL Result;
BlockWindows();
if(String = BuildString(Name,From,To,Type,FALSE,TheFile,TransferInfoPtr ? *TransferInfoPtr : NULL,&Error))
{
ClearSerial();
Result = LaunchCommand(String);
RestartSerial();
if(TransferInfoPtr)
{
FreeFileTransferInfo(*TransferInfoPtr);
*TransferInfoPtr = NULL;
}
FreeVecPooled(String);
}
else
Result = FALSE;
ReleaseWindows();
return(Result);
}
else
{
struct FileRequester *FileRequest;
UBYTE DummyBuffer[MAX_FILENAME_LENGTH];
STRPTR UploadPath;
BOOL DidSend = TRUE;
BPTR NewDir = NULL,
OldDir = NULL;
/* We are uploading data. */
Uploading = TRUE;
/* Select the upload path. */
switch(Type)
{
case TRANSFER_BINARY:
UploadPath = Config->PathConfig->BinaryUploadPath;
break;
case TRANSFER_TEXT:
UploadPath = Config->PathConfig->TextUploadPath;
break;
case TRANSFER_ASCII:
UploadPath = Config->PathConfig->ASCIIUploadPath;
break;
}
if(UploadPath[0])
{
if(NewDir = Lock(UploadPath,ACCESS_READ))
OldDir = CurrentDir(NewDir);
}
BlockWindows();
/* If not initialized, try to set up a new
* external transfer protocol.
*/
if(!XProtocolBase)
{
if(SelectProtocol(Window))
{
if(ProtocolSetup(FALSE))
SaveProtocolOpts();
}
}
if(XProtocolBase)
{
SetTransferMenu(TRUE);
/* Do we need to use our own file requester or
* will xpr handle this job for us?
*/
if((TransferBits & XPRS_NOSNDREQ) || TheFile || TransferInfoPtr)
{
if(TheFile)
XprIO->xpr_filename = TheFile;
if(TransferInfoPtr)
XprIO->xpr_filename = (*TransferInfoPtr)->CurrentFile->Name;
CommonStartSendXPR(Type,IsBinary,WaitForIt);
if(TransferInfoPtr)
{
FreeFileTransferInfo(*TransferInfoPtr);
*TransferInfoPtr = NULL;
}
}
else
{
/* We will need the file requester to find
* out which file(s) are to be transferred.
* Multiple files and wildcards are
* supported as well as plain file names.
*/
DummyBuffer[0] = 0;
if(FileRequest = OpenSeveralFiles(Window,LocaleString(MSG_TERMTRANSFER_UPLOAD_FILE_TXT + (Type - TRANSFER_BINARY)),LocaleString(MSG_TERMTRANSFER_SEND_TXT),NULL,DummyBuffer,sizeof(DummyBuffer)))
{
strcpy(UploadPath,FileRequest->fr_Drawer);
ConfigChanged = TRUE;
if(FileTransferInfo = BuildFileTransferInfo(FileRequest))
{
/* Make sure that at least the
* first file gets transferred
* in case the protocol does
* no support batch upload.
*/
XprIO->xpr_filename = ReplaceName(FileTransferInfo->CurrentFile->Name);
CommonStartSendXPR(Type,IsBinary,WaitForIt);
if(FileTransferInfo)
{
FreeFileTransferInfo(FileTransferInfo);
FileTransferInfo = NULL;
}
}
FreeAslRequest(FileRequest);
}
else
DidSend = FALSE;
}
}
else
SetTransferMenu(TRUE);
if(NewDir)
UnLock(CurrentDir(OldDir));
CommonSendXPRCleanup(WaitForIt);
return(DidSend);
}
}
/* SelectProtocol(STRPTR Name,struct Window *ParentWindow):
*
* Select a different transfer protocol library using
* the asl.library file requester.
*/
STATIC BOOL
SelectProtocol(struct Window *ParentWindow)
{
UBYTE LocalBuffer[MAX_FILENAME_LENGTH];
strcpy(LocalBuffer,LastXprLibrary);
if(PickFile(ParentWindow,"Libs:","xpr#?.library",LocaleString(MSG_TERMXPR_SELECT_TRANSFER_PROTOCOL_TXT),LocalBuffer,NT_LIBRARY))
{
if(Stricmp(LocalBuffer,LastXprLibrary))
{
strcpy(LastXprLibrary,LocalBuffer);
return(TRUE);
}
}
return(FALSE);
}
/* StartSend(BOOL IsBinary):
*
* Start sending files with the XPR protocol.
*/
STATIC BOOL
StartSend(BOOL IsBinary)
{
if(ReadRequest && WriteRequest)
{
BOOL Failed;
BinaryTransfer = IsBinary;
if(XProtocolSend(XprIO))
Failed = FALSE;
else
Failed = TRUE;
/* Always return to binary transfer mode */
BinaryTransfer = TRUE;
/* In case the transfer has been aborted,
* flush the input buffer of dirty data.
*/
if(TransferAborted)
CompletelyFlushSerialRead();
return(Failed);
}
else
return(TRUE);
}
/* StartReceive(BOOL IsBinary):
*
* Start receiving files with the XPR protocol.
*/
STATIC BOOL
StartReceive(BOOL IsBinary)
{
if(ReadRequest && WriteRequest)
{
BOOL Failed;
BinaryTransfer = IsBinary;
if(XProtocolReceive(XprIO))
Failed = FALSE;
else
Failed = TRUE;
/* Always return to binary transfer mode */
BinaryTransfer = TRUE;
return(Failed);
}
else
return(TRUE);
}
/* StripLibrary(STRPTR Protocol,STRPTR NameBuffer):
*
* Strip the .library part from a file name.
*/
STATIC VOID
StripLibrary(STRPTR Protocol,STRPTR NameBuffer,LONG NameSize)
{
LONG i;
CopyMem(FilePart(Protocol),NameBuffer,NameSize - 1);
NameBuffer[NameSize - 1] = 0;
for(i = strlen(NameBuffer) - 1 ; i >= 0 ; i--)
{
if(NameBuffer[i] == '.')
{
NameBuffer[i] = 0;
break;
}
}
}
/* IsZModem(STRPTR String):
*
* Checks if a file name has a "zmodem" string embedded.
*/
STATIC BOOL
IsZModem(STRPTR String)
{
LONG i;
for(i = 0 ; i <= strlen(String) - 6 ; i++)
{
if(!Stricmp(&String[i],"zmodem"))
return(TRUE);
}
return(FALSE);
}
/* CommonExternalSetup(STRPTR Buffer):
*
* Set up the name of an external file transfer protocol.
*/
STATIC VOID
CommonExternalSetup(STRPTR Buffer)
{
UBYTE NameBuffer[MAX_FILENAME_LENGTH];
LONG i;
while(*Buffer == ' ')
Buffer++;
if(!Strnicmp(Buffer,"run",3))
Buffer += 3;
while(*Buffer == ' ')
Buffer++;
CopyMem(FilePart(Buffer),NameBuffer,sizeof(NameBuffer) - 1);
NameBuffer[sizeof(NameBuffer) - 1] = 0;
for(i = 0 ; i < sizeof(NameBuffer) ; i++)
{
if(NameBuffer[i] == ' ')
{
NameBuffer[i] = 0;
break;
}
}
NameBuffer[0] = ToUpper(NameBuffer[0]);
strcpy(TransferProtocolName,NameBuffer);
UsesZModem = IsZModem(NameBuffer);
SetTransferMenu(TRUE);
}
/* CommonXPRSetup(STRPTR ProtocolName,BOOL IgnoreOptions):
*
* Set up and initialize an XPR file transfer protocol.
*/
STATIC BOOL
CommonXPRSetup(STRPTR ProtocolName,BOOL IgnoreOptions)
{
UBYTE NameBuffer[MAX_FILENAME_LENGTH];
BOOL Result;
/* Clear the XPR interface buffer. */
memset(XprIO,0,sizeof(struct XPR_IO));
/* Copy the name of the library. */
StripLibrary(ProtocolName,NameBuffer,sizeof(NameBuffer));
/* Check if the transfer protocol is a sort of ZModem. */
UsesZModem = IsZModem(NameBuffer);
/* Reset the scanner. */
ResetDataFlowFilter();
/* Obtain the protocol default settings. */
if(IgnoreOptions)
ProtocolOptsBuffer[0] = 0;
else
GetEnvDOS(NameBuffer,ProtocolOptsBuffer,sizeof(ProtocolOptsBuffer));
NameBuffer[3] = ToUpper(NameBuffer[3]);
/* Initialize the interface structure. */
XprIO->xpr_filename = ProtocolOptsBuffer;
XprIO->xpr_extension = 4;
#ifdef USE_GLUE
XprIO->xpr_fopen = xpr_fopen_glue;
XprIO->xpr_fclose = xpr_fclose_glue;
XprIO->xpr_fread = xpr_fread_glue;
XprIO->xpr_fwrite = xpr_fwrite_glue;
XprIO->xpr_sread = xpr_sread_glue;
XprIO->xpr_swrite = xpr_swrite_glue;
XprIO->xpr_sflush = xpr_sflush;
XprIO->xpr_update = xpr_update_glue;
XprIO->xpr_chkabort = xpr_chkabort;
XprIO->xpr_gets = xpr_gets_glue;
XprIO->xpr_setserial = xpr_setserial_glue;
XprIO->xpr_ffirst = xpr_ffirst_glue;
XprIO->xpr_fnext = xpr_fnext_glue;
XprIO->xpr_finfo = xpr_finfo_glue;
XprIO->xpr_fseek = xpr_fseek_glue;
XprIO->xpr_options = xpr_options_glue;
XprIO->xpr_unlink = xpr_unlink_glue;
XprIO->xpr_squery = xpr_squery;
XprIO->xpr_getptr = xpr_getptr_glue;
#else
XprIO->xpr_fopen = xpr_fopen;
XprIO->xpr_fclose = xpr_fclose;
XprIO->xpr_fread = xpr_fread;
XprIO->xpr_fwrite = xpr_fwrite;
XprIO->xpr_sread = xpr_sread;
XprIO->xpr_swrite = xpr_swrite;
XprIO->xpr_sflush = xpr_sflush;
XprIO->xpr_update = xpr_update;
XprIO->xpr_chkabort = xpr_chkabort;
XprIO->xpr_gets = xpr_gets;
XprIO->xpr_setserial = xpr_setserial;
XprIO->xpr_ffirst = xpr_ffirst;
XprIO->xpr_fnext = xpr_fnext;
XprIO->xpr_finfo = xpr_finfo;
XprIO->xpr_fseek = xpr_fseek;
XprIO->xpr_options = xpr_options;
XprIO->xpr_unlink = xpr_unlink;
XprIO->xpr_squery = xpr_squery;
XprIO->xpr_getptr = xpr_getptr;
#endif /* USE_GLUE */
/* No success so far */
Result = FALSE;
/* Try to open the library. */
if(XProtocolBase = (struct Library *)OpenLibrary(ProtocolName,0))
{
/* Set up the library. */
ClearSerial();
TransferBits = XProtocolSetup(XprIO);
SerWriteUpdate();
RestartSerial();
DeleteTransferPanel(TRUE);
/* Successful initialization? */
if(TransferBits & XPRS_SUCCESS)
{
strcpy(LastXprLibrary,ProtocolName);
if(TransferBits & XPRS_HOSTNOWAIT)
{
if(!HostReadBuffer)
HostReadBuffer = AllocVecPooled(Config->SerialConfig->SerialBufferSize,MEMF_ANY);
}
else
{
FreeVecPooled(HostReadBuffer);
HostReadBuffer = NULL;
}
strcpy(TransferProtocolName,&NameBuffer[3]);
Result = TRUE;
}
}
if(!Result)
{
ShowRequest(Window,LocaleString(MSG_GLOBAL_FAILED_TO_SET_UP_PROTOCOL_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT),FilePart(ProtocolName));
CloseLibrary(XProtocolBase);
XProtocolBase = NULL;
SerWriteUpdate();
LastXprLibrary[0] = 0;
TransferBits = 0;
TransferProtocolName[0] = 0;
}
ConTransferUpdate();
SetTransferMenu(TRUE);
return(Result);
}
/* CreateArgName(STRPTR String):
*
* Create another node based upon a string given.
* Encloses parameters in quotes if necessary and
* `escapes' quotes.
*/
STATIC struct Node *
CreateArgName(STRPTR String)
{
struct Node *Node;
STRPTR Index = String;
LONG Len,NewLen;
BOOL Quotes = FALSE;
Len = NewLen = strlen(String);
while(*Index)
{
if(*Index == '\"')
NewLen++;
if(*Index == ' ' && !Quotes)
{
NewLen += 2;
Quotes = TRUE;
}
Index++;
}
if(!Len)
{
NewLen += 2;
Quotes = TRUE;
}
if(NewLen > Len)
{
if(Node = (struct Node *)AllocVecPooled(sizeof(struct Node) + NewLen + 1,MEMF_ANY))
{
STRPTR Dest;
Node->ln_Name = (STRPTR)(Node + 1);
Dest = Node->ln_Name;
Index = String;
if(Quotes)
*Dest++ = '\"';
while(*Index)
{
if(*Index == '\"')
*Dest++ = '*';
*Dest++ = *Index++;
}
if(Quotes)
*Dest++ = '\"';
*Dest = 0;
}
}
else
{
if(Node = (struct Node *)AllocVecPooled(sizeof(struct Node) + Len + 1,MEMF_ANY))
strcpy(Node->ln_Name = (STRPTR)(Node + 1),String);
}
return(Node);
}
/* BuildString():
*
* Build a command line based upon a template and
* existing file transfer info.
*/
STATIC STRPTR
BuildString(STRPTR Source,STRPTR From,STRPTR To,BYTE Type,BOOL ReceiveMode,STRPTR SingleFile,struct FileTransferInfo *Info,LONG *Error)
{
struct List *List;
STRPTR Result = NULL;
if(Info)
{
if(!IsListEmpty((struct List *)Info))
Info->CurrentFile = (struct FileTransferNode *)Info->FileList.mlh_Head;
else
Info = NULL;
}
*Error = 0;
if(List = CreateList())
{
UBYTE LocalBuffer[MAX_FILENAME_LENGTH],TempBuffer[MAX_FILENAME_LENGTH];
struct FileRequester *FileRequest;
STRPTR Index,Dest;
struct Node *Node;
Index = Source;
Dest = LocalBuffer;
while(*Index && !(*Error))
{
if(*Index == '%')
{
struct Node *InsertHere = List->lh_TailPred;
BOOL InsertBefore = TRUE;
Index++;
if(!(*Index))
{
*Dest = 0;
if(LocalBuffer[0])
{
if(Node = CreateNode(LocalBuffer))
{
AddTail(List,Node);
LocalBuffer[0] = 0;
}
else
*Error = ERROR_NO_FREE_STORE;
}
break;
}
switch(*Index)
{
case 'f':
if(SingleFile)
{
if(Node = CreateArgName(SingleFile))
AddTail(List,Node);
else
*Error = ERROR_NO_FREE_STORE;
SingleFile = NULL;
break;
}
if(Info)
{
if(Node = CreateArgName(Info->CurrentFile->Name))
AddTail(List,Node);
else
*Error = ERROR_NO_FREE_STORE;
if(Info->CurrentFile->MinNode.mln_Succ)
Info->CurrentFile = (struct FileTransferNode *)Info->CurrentFile->MinNode.mln_Succ;
else
Info = NULL;
break;
}
LT_LockWindow(Window);
if(ReceiveMode)
{
LimitedStrcpy(sizeof(TempBuffer),TempBuffer,To);
FileRequest = SaveFile(Window,LocaleString(MSG_TERMTRANSFER_DOWNLOAD_FILE_TXT + Type),LocaleString(MSG_TERMTRANSFER_RECEIVE_TXT),NULL,TempBuffer,sizeof(TempBuffer));
}
else
{
LimitedStrcpy(sizeof(TempBuffer),TempBuffer,From);
FileRequest = OpenSingleFile(Window,LocaleString(MSG_TERMTRANSFER_UPLOAD_FILE_TXT + Type),LocaleString(MSG_TERMTRANSFER_SEND_TXT),NULL,TempBuffer,sizeof(TempBuffer));
}
if(FileRequest)
{
if(Node = CreateArgName(TempBuffer))
AddTail(List,Node);
else
*Error = ERROR_NO_FREE_STORE;
FreeAslRequest(FileRequest);
}
else
*Error = ERR_ABORTED;
LT_UnlockWindow(Window);
break;
case 'F':
if(SingleFile)
{
if(Node = CreateArgName(FilePart(SingleFile)))
AddTail(List,Node);
else
*Error = ERROR_NO_FREE_STORE;
SingleFile = NULL;
break;
}
if(Info)
{
if(Node = CreateArgName(FilePart(Info->CurrentFile->Name)))
AddTail(List,Node);
else
*Error = ERROR_NO_FREE_STORE;
if(Info->CurrentFile->MinNode.mln_Succ)
Info->CurrentFile = (struct FileTransferNode *)Info->CurrentFile->MinNode.mln_Succ;
else
Info = NULL;
break;
}
LT_LockWindow(Window);
if(ReceiveMode)
{
LimitedStrcpy(sizeof(TempBuffer),TempBuffer,To);
FileRequest = SaveFile(Window,LocaleString(MSG_TERMTRANSFER_DOWNLOAD_FILE_TXT + Type),LocaleString(MSG_TERMTRANSFER_RECEIVE_TXT),NULL,TempBuffer,sizeof(TempBuffer));
}
else
{
LimitedStrcpy(sizeof(TempBuffer),TempBuffer,From);
FileRequest = OpenSingleFile(Window,LocaleString(MSG_TERMTRANSFER_UPLOAD_FILE_TXT + Type),LocaleString(MSG_TERMTRANSFER_SEND_TXT),NULL,TempBuffer,sizeof(TempBuffer));
}
if(FileRequest)
{
if(Node = CreateArgName(FilePart(TempBuffer)))
AddTail(List,Node);
else
*Error = ERROR_NO_FREE_STORE;
FreeAslRequest(FileRequest);
}
else
*Error = ERR_ABORTED;
LT_UnlockWindow(Window);
break;
case 'm':
if(SingleFile)
{
if(Node = CreateArgName(SingleFile))
AddTail(List,Node);
else
*Error = ERROR_NO_FREE_STORE;
SingleFile = NULL;
break;
}
if(Info)
{
struct FileTransferNode *SomeNode;
for(SomeNode = Info->CurrentFile ; SomeNode->MinNode.mln_Succ && !(*Error) ; SomeNode = (struct FileTransferNode *)SomeNode->MinNode.mln_Succ)
{
if(Node = CreateArgName(SomeNode->Name))
AddTail(List,Node);
else
*Error = ERROR_NO_FREE_STORE;
}
Info = NULL;
break;
}
LT_LockWindow(Window);
if(ReceiveMode)
{
LimitedStrcpy(sizeof(TempBuffer),TempBuffer,To);
FileRequest = SaveFile(Window,LocaleString(MSG_TERMTRANSFER_DOWNLOAD_FILE_TXT + Type),LocaleString(MSG_TERMTRANSFER_RECEIVE_TXT),NULL,TempBuffer,sizeof(TempBuffer));
}
else
{
LimitedStrcpy(sizeof(TempBuffer),TempBuffer,From);
FileRequest = OpenSeveralFiles(Window,LocaleString(MSG_TERMTRANSFER_UPLOAD_FILE_TXT + Type),LocaleString(MSG_TERMTRANSFER_SEND_TXT),NULL,TempBuffer,sizeof(TempBuffer));
}
LT_UnlockWindow(Window);
if(FileRequest)
{
LONG i;
if(TempBuffer[0] && FileRequest->fr_NumArgs == 1)
{
if(Node = CreateArgName(TempBuffer))
{
AddTail(List,Node);
break;
}
else
*Error = ERROR_NO_FREE_STORE;
}
for(i = 0 ; i < FileRequest->fr_NumArgs && !(*Error) ; i++)
{
if(FileRequest->fr_ArgList[i].wa_Lock)
{
if(NameFromLock(FileRequest->fr_ArgList[i].wa_Lock,TempBuffer,sizeof(TempBuffer)))
{
if(AddPart(TempBuffer,FileRequest->fr_ArgList[i].wa_Name,sizeof(TempBuffer)))
{
if(Node = CreateArgName(TempBuffer))
AddTail(List,Node);
else
*Error = ERROR_NO_FREE_STORE;
}
else
*Error = IoErr();
}
else
*Error = IoErr();
}
else
{
LimitedStrcpy(sizeof(TempBuffer),TempBuffer,FileRequest->fr_Drawer);
if(AddPart(TempBuffer,FileRequest->fr_ArgList[i].wa_Name,sizeof(TempBuffer)))
{
if(Node = CreateArgName(TempBuffer))
AddTail(List,Node);
else
*Error = ERROR_NO_FREE_STORE;
}
else
*Error = IoErr();
}
}
FreeAslRequest(FileRequest);
}
else
*Error = ERR_ABORTED;
break;
case 'M':
if(SingleFile)
{
if(Node = CreateArgName(FilePart(SingleFile)))
AddTail(List,Node);
else
*Error = ERROR_NO_FREE_STORE;
SingleFile = NULL;
break;
}
if(Info)
{
struct FileTransferNode *SomeNode;
for(SomeNode = Info->CurrentFile ; SomeNode->MinNode.mln_Succ && !(*Error) ; SomeNode = (struct FileTransferNode *)SomeNode->MinNode.mln_Succ)
{
if(Node = CreateArgName(FilePart(SomeNode->Name)))
AddTail(List,Node);
else
*Error = ERROR_NO_FREE_STORE;
}
Info = NULL;
break;
}
LT_LockWindow(Window);
if(ReceiveMode)
{
LimitedStrcpy(sizeof(TempBuffer),TempBuffer,To);
FileRequest = SaveFile(Window,LocaleString(MSG_TERMTRANSFER_DOWNLOAD_FILE_TXT + Type),LocaleString(MSG_TERMTRANSFER_RECEIVE_TXT),NULL,TempBuffer,sizeof(TempBuffer));
}
else
{
LimitedStrcpy(sizeof(TempBuffer),TempBuffer,From);
FileRequest = OpenSeveralFiles(Window,LocaleString(MSG_TERMTRANSFER_UPLOAD_FILE_TXT + Type),LocaleString(MSG_TERMTRANSFER_SEND_TXT),NULL,TempBuffer,sizeof(TempBuffer));
}
LT_UnlockWindow(Window);
if(FileRequest)
{
LONG i;
if(TempBuffer[0] && FileRequest->fr_NumArgs == 1)
{
if(Node = CreateArgName(FilePart(TempBuffer)))
{
AddTail(List,Node);
break;
}
else
*Error = ERROR_NO_FREE_STORE;
}
for(i = 0 ; i < FileRequest->fr_NumArgs && !(*Error) ; i++)
{
if(FileRequest->fr_ArgList[i].wa_Lock)
{
if(AddPart(TempBuffer,FileRequest->fr_ArgList[i].wa_Name,sizeof(TempBuffer)))
{
if(Node = CreateArgName(TempBuffer))
AddTail(List,Node);
else
*Error = ERROR_NO_FREE_STORE;
}
else
*Error = IoErr();
}
else
{
if(Node = CreateArgName(FileRequest->fr_ArgList[i].wa_Name))
AddTail(List,Node);
else
*Error = ERROR_NO_FREE_STORE;
}
}
FreeAslRequest(FileRequest);
}
else
*Error = ERR_ABORTED;
break;
case 'b':
case 'B':
if(Node = CreateNodeArgs("%ld",Config->SerialConfig->BaudRate))
AddTail(List,Node);
else
*Error = ERROR_NO_FREE_STORE;
break;
case 'c':
case 'C':
if(Node = CreateNodeArgs("%ld",DTERate ? DTERate : Config->SerialConfig->BaudRate))
AddTail(List,Node);
else
*Error = ERROR_NO_FREE_STORE;
break;
case 'p':
case 'P':
if(Node = CreateArgName(RexxPortName))
AddTail(List,Node);
else
*Error = ERROR_NO_FREE_STORE;
break;
case 'd':
case 'D':
if(Node = CreateArgName(Config->SerialConfig->SerialDevice))
AddTail(List,Node);
else
*Error = ERROR_NO_FREE_STORE;
break;
case 'u':
case 'U':
if(Node = CreateNodeArgs("%ld",Config->SerialConfig->UnitNumber))
AddTail(List,Node);
else
*Error = ERROR_NO_FREE_STORE;
break;
case '<':
if(Node = CreateArgName(From))
AddTail(List,Node);
else
*Error = ERROR_NO_FREE_STORE;
break;
case '>':
if(Node = CreateArgName(To))
AddTail(List,Node);
else
*Error = ERROR_NO_FREE_STORE;
break;
case 's':
case 'S':
if(!GetPubScreenName(Window->WScreen,TempBuffer))
TempBuffer[0] = 0;
if(Node = CreateArgName(TempBuffer))
AddTail(List,Node);
else
*Error = ERROR_NO_FREE_STORE;
break;
default:
*Dest = *Index;
InsertBefore = FALSE;
break;
}
if(InsertBefore && Node)
{
struct Node *OtherNode;
*Dest = 0;
if(LocalBuffer[0])
{
if(OtherNode = CreateNode(LocalBuffer))
{
Insert(List,OtherNode,InsertHere);
LocalBuffer[0] = 0;
}
else
*Error = ERROR_NO_FREE_STORE;
}
Dest = LocalBuffer;
}
}
else
*Dest++ = *Index;
Index++;
}
*Dest = 0;
if(LocalBuffer[0] && !(*Error))
{
if(Node = CreateNode(LocalBuffer))
AddTail(List,Node);
else
*Error = ERROR_NO_FREE_STORE;
}
if(!(*Error))
{
if(!IsListEmpty(List))
{
LONG Total = 0,Len;
for(Node = List->lh_Head ; Node->ln_Succ ; Node = Node->ln_Succ)
Total += strlen(Node->ln_Name) + 1;
if(Result = (STRPTR)AllocVecPooled(Total,MEMF_ANY))
{
STRPTR Buffer = Result;
for(Node = List->lh_Head ; Node->ln_Succ ; Node = Node->ln_Succ)
{
Len = strlen(Node->ln_Name);
CopyMem(Node->ln_Name,Buffer,Len);
Buffer += Len;
*Buffer++ = ' ';
}
Buffer[-1] = 0;
}
}
else
Result = "";
}
DeleteList(List);
}
else
*Error = ERROR_NO_FREE_STORE;
return(Result);
}
/* ReplaceName(STRPTR Original):
*
* Replace a filename with a mangled version for
* file uploads.
*/
STATIC STRPTR
ReplaceName(STRPTR Source)
{
if(Config->TransferConfig->MangleFileNames)
{
UBYTE LocalName[MAX_FILENAME_LENGTH],*Char;
LimitedStrcpy(sizeof(OriginalName),OriginalName,Source);
ShrinkName(FilePart(Source),LocalName,12,TRUE);
LimitedStrcpy(sizeof(ShrunkenName),ShrunkenName,Source);
Char = PathPart(ShrunkenName);
*Char = 0;
if(AddPart(ShrunkenName,LocalName,sizeof(ShrunkenName)))
return(ShrunkenName);
}
OriginalName[0] = 0;
return(Source);
}
/* CommonStartSendXPR():
*
* Start sending files using the XPR protocol.
*/
STATIC VOID
CommonStartSendXPR(LONG Type,BOOL IsBinary,BOOL WaitForIt)
{
PushStatus(STATUS_UPLOAD);
if(TransferPanel(LocaleString(MSG_TERMTRANSFER_UPLOAD_FILE_TXT + (Type - TRANSFER_BINARY))))
{
ClearSerial();
LogAction(LocaleString(MSG_TERMTRANSFER_LOGMSG_INITIATE_UPLOAD_TXT),LocaleString(MSG_TERMTRANSFER_BINARY_TXT + (Type - TRANSFER_BINARY)));
TransferFailed = StartSend(IsBinary);
/* Tell the user what happened */
if(TransferFailed || TransferAborted)
Say(LocaleString(MSG_GLOBAL_TRANSFER_FAILED_OR_ABORTED_TXT));
else
Say(LocaleString(MSG_GLOBAL_TRANSFER_COMPLETED_TXT));
if(TransferFailed || TransferError)
{
if(Config->TransferConfig->TransferNotification == XFERNOTIFY_ALWAYS || Config->TransferConfig->TransferNotification == XFERNOTIFY_END)
WakeUp(TransferWindow,SOUND_BADTRANSFER);
DeleteTransferPanel(WaitForIt);
}
else
{
if(TransferWindow)
{
if(Config->TransferConfig->TransferNotification == XFERNOTIFY_ALWAYS || Config->TransferConfig->TransferNotification == XFERNOTIFY_END)
WakeUp(TransferWindow,SOUND_GOODTRANSFER);
DelayTime(2,0);
}
DeleteTransferPanel(FALSE);
}
RestartSerial();
}
PopStatus();
}
/* CommonSendXPRCleanup(BOOL WaitForIt):
*
* Do the cleanup work after a file transfer has finished.
*/
STATIC VOID
CommonSendXPRCleanup(BOOL WaitForIt)
{
if(SendAbort)
{
CancelZModem();
SendAbort = FALSE;
}
ReleaseWindows();
Uploading = FALSE;
if(WaitForIt)
{
if(Config->CommandConfig->UploadMacro[0])
SerialCommand(Config->CommandConfig->UploadMacro);
}
DidTransfer = FALSE;
}
/* CommonStartReceiveXPR():
*
* Start receiving files using the XPR protocol.
*/
STATIC VOID
CommonStartReceiveXPR(LONG Type,BOOL IsBinary,BOOL WaitForIt)
{
PushStatus(STATUS_DOWNLOAD);
/* Open the transfer panel. */
if(TransferPanel(LocaleString(MSG_TERMTRANSFER_DOWNLOAD_FILE_TXT + (Type - TRANSFER_BINARY))))
{
ClearSerial();
LogAction(LocaleString(MSG_TERMTRANSFER_LOGMSG_INITIATE_DOWNLOAD_TXT),LocaleString(MSG_TERMTRANSFER_BINARY_TXT + (Type - TRANSFER_BINARY)));
/* Receive the file. */
TransferFailed = StartReceive(IsBinary);
if(TransferAborted || TransferFailed)
Say(LocaleString(MSG_GLOBAL_TRANSFER_FAILED_OR_ABORTED_TXT));
else
Say(LocaleString(MSG_GLOBAL_TRANSFER_COMPLETED_TXT));
if(TransferFailed || TransferError)
{
if(Config->TransferConfig->TransferNotification == XFERNOTIFY_ALWAYS || Config->TransferConfig->TransferNotification == XFERNOTIFY_END)
WakeUp(TransferWindow,SOUND_BADTRANSFER);
DeleteTransferPanel(WaitForIt);
}
else
{
if(TransferWindow)
{
if(Config->TransferConfig->TransferNotification == XFERNOTIFY_ALWAYS || Config->TransferConfig->TransferNotification == XFERNOTIFY_END)
WakeUp(TransferWindow,SOUND_GOODTRANSFER);
DelayTime(2,0);
}
DeleteTransferPanel(FALSE);
}
/* Queue another read
* request.
*/
RestartSerial();
}
PopStatus();
}
/* TransferCompare(struct FileTransferNode **A,struct FileTransferNode **B):
*
* Local subroutine required by QuickSort().
*/
STATIC LONG
TransferCompare(struct FileTransferNode **A,struct FileTransferNode **B)
{
if((*A)->Size > (*B)->Size)
return(-1);
else
{
if((*A)->Size < (*B)->Size)
return(1);
else
return(Stricmp(FilePart((*A)->Name),FilePart((*B)->Name)));
}
}
/* FreeFileTransferInfo(struct FileTransferInfo *Info):
*
* Free a file transfer info list as allocated
* by AllocFileTransferInfo() and AddFileTransferNode().
*/
VOID
FreeFileTransferInfo(struct FileTransferInfo *Info)
{
if(Info)
{
struct FileTransferNode *Node,*Next;
for(Node = (struct FileTransferNode *)Info->FileList.mlh_Head ; Next = (struct FileTransferNode *)Node->MinNode.mln_Succ ; Node = Next)
FreeVecPooled(Node);
FreeVecPooled(Info);
}
}
/* AllocFileTransferInfo():
*
* Allocate a FileTransferInfo structure for use with
* AddFileTransferNode().
*/
struct FileTransferInfo *
AllocFileTransferInfo()
{
struct FileTransferInfo *Info;
if(Info = (struct FileTransferInfo *)AllocVecPooled(sizeof(struct FileTransferInfo),MEMF_ANY | MEMF_CLEAR))
{
NewList((struct List *)&Info->FileList);
return(Info);
}
return(NULL);
}
/* AddFileTransferNode(struct FileTransferInfo *Info,STRPTR Name,ULONG Size):
*
* Allocate a file transfer information node.
*/
BOOL
AddFileTransferNode(struct FileTransferInfo *Info,STRPTR Name,ULONG Size)
{
struct FileTransferNode *Node;
if(Node = (struct FileTransferNode *)AllocVecPooled(sizeof(struct FileTransferNode) + strlen(Name) + 1,MEMF_ANY))
{
Node->Size = Size;
Node->Name = (STRPTR)(Node + 1);
strcpy(Node->Name,Name);
AddTail((struct List *)&Info->FileList,(struct Node *)Node);
Info->TotalSize += Size;
Info->TotalFiles++;
return(TRUE);
}
else
return(FALSE);
}
/* ReadyFileTransferInfo(struct FileTransferInfo *Info,BOOL SortIt):
*
* Sorts the file transfer information list in ascending
* order, but makes sure that the files are sorted
* in descending order (i.e. the larger files come
* first and files of equal size are sorted
* lexically).
*/
VOID
ReadyFileTransferInfo(struct FileTransferInfo *Info,BOOL SortIt)
{
if(Info->TotalFiles > 1 && SortIt)
{
struct FileTransferNode **NodeTable;
if(NodeTable = (struct FileTransferNode **)AllocVecPooled(sizeof(struct FileTransferNode *) * Info->TotalFiles,MEMF_ANY))
{
struct FileTransferNode *Node;
LONG i;
for(Node = (struct FileTransferNode *)Info->FileList.mlh_Head, i = 0 ; Node->MinNode.mln_Succ ; Node = (struct FileTransferNode *)Node->MinNode.mln_Succ, i++)
NodeTable[i] = Node;
qsort(NodeTable,Info->TotalFiles,sizeof(struct FileTransferNode *),(SORTFUNC)TransferCompare);
NewList((struct List *)&Info->FileList);
for(i = 0 ; i < Info->TotalFiles ; i++)
AddTail((struct List *)&Info->FileList,(struct Node *)NodeTable[i]);
FreeVecPooled(NodeTable);
}
}
Info->DoneSize = 0;
Info->DoneFiles = 0;
Info->CurrentFile = (struct FileTransferNode *)Info->FileList.mlh_Head;
Info->CurrentSize = Info->CurrentFile->Size;
}
/* BuildFileTransferInfo(struct FileRequester *FileRequester):
*
* Build a file transfer information list from
* information provided by a FileRequester structure.
*/
struct FileTransferInfo *
BuildFileTransferInfo(struct FileRequester *FileRequester)
{
struct FileTransferInfo *Info;
LONG FilesFound;
FilesFound = 0;
if(Info = AllocFileTransferInfo())
{
BOOL Success = FALSE;
BPTR NewLock,OldLock;
if(NewLock = Lock(FileRequester->fr_Drawer,ACCESS_READ))
{
OldLock = CurrentDir(NewLock);
if(FileRequester->fr_NumArgs)
{
struct WBArg *ArgList;
BPTR FileLock;
LONG i;
D_S(struct FileInfoBlock,FileInfo);
ArgList = FileRequester->fr_ArgList;
Success = TRUE;
for(i = 0 ; Success && i < FileRequester->fr_NumArgs ; i++)
{
if(ArgList[i].wa_Name)
{
if(ArgList[i].wa_Lock)
{
CurrentDir(ArgList[i].wa_Lock);
if(FileLock = Lock(ArgList[i].wa_Name,ACCESS_READ))
{
if(Examine(FileLock,FileInfo))
{
if(FileInfo->fib_DirEntryType < 0)
{
UBYTE LocalBuffer[MAX_FILENAME_LENGTH];
if(NameFromLock(FileLock,LocalBuffer,sizeof(LocalBuffer)))
{
if(!AddFileTransferNode(Info,LocalBuffer,FileInfo->fib_Size))
Success = FALSE;
else
FilesFound++;
}
}
}
UnLock(FileLock);
}
CurrentDir(NewLock);
}
else
{
if(FileLock = Lock(ArgList[i].wa_Name,ACCESS_READ))
{
if(Examine(FileLock,FileInfo))
{
if(FileInfo->fib_DirEntryType < 0)
{
UBYTE LocalBuffer[MAX_FILENAME_LENGTH];
if(NameFromLock(FileLock,LocalBuffer,sizeof(LocalBuffer)))
{
if(!AddFileTransferNode(Info,LocalBuffer,FileInfo->fib_Size))
Success = FALSE;
else
FilesFound++;
}
}
}
UnLock(FileLock);
}
}
}
}
}
else
{
struct AnchorPath *Anchor;
STRPTR FileName;
if(FileRequester->fr_NumArgs > 1 && FileRequester->fr_ArgList)
FileName = FileRequester->fr_ArgList->wa_Name;
else
FileName = FileRequester->fr_File;
if(Anchor = (struct AnchorPath *)AllocVecPooled(sizeof(struct AnchorPath),MEMF_ANY | MEMF_CLEAR))
{
if(!MatchFirst(FileName,Anchor))
{
Success = TRUE;
if(Anchor->ap_Info.fib_DirEntryType < 0)
{
UBYTE LocalBuffer[MAX_FILENAME_LENGTH];
if(NameFromLock(NewLock,LocalBuffer,sizeof(LocalBuffer)))
{
if(AddPart(LocalBuffer,Anchor->ap_Info.fib_FileName,sizeof(LocalBuffer)))
{
if(!AddFileTransferNode(Info,LocalBuffer,Anchor->ap_Info.fib_Size))
Success = FALSE;
else
FilesFound++;
}
}
}
if(Success)
{
while(!MatchNext(Anchor))
{
UBYTE LocalBuffer[MAX_FILENAME_LENGTH];
if(NameFromLock(NewLock,LocalBuffer,sizeof(LocalBuffer)))
{
if(AddPart(LocalBuffer,Anchor->ap_Info.fib_FileName,sizeof(LocalBuffer)))
{
if(!AddFileTransferNode(Info,LocalBuffer,Anchor->ap_Info.fib_Size))
{
Success = FALSE;
break;
}
else
FilesFound++;
}
}
}
}
if(IoErr() != ERROR_NO_MORE_ENTRIES)
Success = FALSE;
}
MatchEnd(Anchor);
FreeVecPooled(Anchor);
}
}
UnLock(CurrentDir(OldLock));
}
if(Success && FilesFound)
{
ReadyFileTransferInfo(Info,TRUE);
return(Info);
}
else
FreeFileTransferInfo(Info);
}
return(NULL);
}
VOID
StartReceiveXPR_File(LONG Type,STRPTR Name,BOOL WaitForIt)
{
CommonStartReceive(Type,Name,WaitForIt);
}
VOID
StartReceiveXPR_AskForFile(LONG Type,BOOL WaitForIt)
{
CommonStartReceive(Type,NULL,WaitForIt);
}
BOOL
StartSendXPR_File(LONG Type,STRPTR TheFile,BOOL WaitForIt)
{
return(CommonStartSend(Type,TheFile,NULL,WaitForIt));
}
BOOL
StartSendXPR_AskForFile(LONG Type,BOOL WaitForIt)
{
return(CommonStartSend(Type,NULL,NULL,WaitForIt));
}
BOOL
StartSendXPR_FromList(LONG Type,BOOL WaitForIt)
{
return(CommonStartSend(Type,NULL,&FileTransferInfo,WaitForIt));
}
/* ResetProtocol():
*
* Return to the previously selected file
* transfer protocol.
*/
VOID
ResetProtocol()
{
ChangeProtocol(NULL,XFER_DEFAULT);
}
/* SaveProtocolOpts():
*
* Save the current protocol settings to an environment variable.
*/
VOID
SaveProtocolOpts()
{
/* It's time to save the altered options. */
if(NewOptions && XProtocolBase)
{
UBYTE NameBuffer[MAX_FILENAME_LENGTH];
/* Strip the `.library' part. */
StripLibrary(LastXprLibrary,NameBuffer,sizeof(NameBuffer));
/* Cause the xpr.library to prompt for
* input. We expect the library to fill
* the prompt string with the default
* settings. The resulting string is
* intercepted by xpr_stealopts, saved
* to an environment variable and will
* serve as a reinitialization string
* later.
*/
XprIO->xpr_filename = NULL;
XprIO->xpr_extension = 0;
#ifdef USE_GLUE
XprIO->xpr_gets = xpr_stealopts_glue;
XprIO->xpr_options = NULL;
#else
XprIO->xpr_gets = xpr_stealopts;
XprIO->xpr_options = NULL;
#endif /* USE_GLUE */
ClearSerial();
XProtocolSetup(XprIO);
DeleteTransferPanel(FALSE);
/* Save the options in case anything goes
* wrong.
*/
NewOptions = FALSE;
SetEnvDOS(NameBuffer,ProtocolOptsBuffer);
/* Reinitialize the library. */
XprIO->xpr_filename = ProtocolOptsBuffer;
XprIO->xpr_extension = 4;
#ifdef USE_GLUE
XprIO->xpr_gets = xpr_gets_glue;
XprIO->xpr_options = xpr_options_glue;
#else
XprIO->xpr_gets = xpr_gets;
XprIO->xpr_options = xpr_options;
#endif /* USE_GLUE */
XProtocolSetup(XprIO);
RestartSerial();
DeleteTransferPanel(FALSE);
}
}
/* TransferCleanup():
*
* We did a file transfer (auto-download?) and
* will need to close the transfer window.
*/
VOID
TransferCleanup()
{
if(DidTransfer)
{
if(TransferFailed || TransferError)
{
if(Config->TransferConfig->TransferNotification == XFERNOTIFY_ALWAYS || Config->TransferConfig->TransferNotification == XFERNOTIFY_END)
WakeUp(TransferWindow,SOUND_BADTRANSFER);
DeleteTransferPanel(TRUE);
}
else
{
if(TransferWindow)
{
if(Config->TransferConfig->TransferNotification == XFERNOTIFY_ALWAYS || Config->TransferConfig->TransferNotification == XFERNOTIFY_END)
WakeUp(TransferWindow,SOUND_GOODTRANSFER);
DelayTime(2,0);
}
DeleteTransferPanel(FALSE);
}
if(SendAbort)
{
CancelZModem();
SendAbort = FALSE;
}
if(Config->CommandConfig->DownloadMacro[0])
SerialCommand(Config->CommandConfig->DownloadMacro);
Say(LocaleString(MSG_GLOBAL_TRANSFER_COMPLETED_TXT));
DidTransfer = FALSE;
}
else
{
if(TransferFailed || TransferError)
{
if(Config->TransferConfig->TransferNotification == XFERNOTIFY_ALWAYS || Config->TransferConfig->TransferNotification == XFERNOTIFY_END)
WakeUp(TransferWindow,SOUND_BADTRANSFER);
DeleteTransferPanel(TRUE);
}
else
{
if(TransferWindow)
{
if(Config->TransferConfig->TransferNotification == XFERNOTIFY_ALWAYS || Config->TransferConfig->TransferNotification == XFERNOTIFY_END)
WakeUp(TransferWindow,SOUND_GOODTRANSFER);
DelayTime(2,0);
}
DeleteTransferPanel(FALSE);
}
}
ReleaseWindows();
}
/* RemoveUploadListItem(STRPTR Name):
*
* Remove a named item from the upload list.
*/
VOID
RemoveUploadListItem(STRPTR Name)
{
BPTR NameLock;
if(NameLock = Lock(Name,ACCESS_READ))
{
struct GenericList *List;
struct Node *Node;
STRPTR Base;
BOOL Done;
List = GenericListTable[GLIST_UPLOAD];
Base = FilePart(Name);
LockGenericList(List);
for(Node = (struct Node *)List->ListHeader.mlh_Head, Done = FALSE ; !Done && Node->ln_Succ ; Node = Node->ln_Succ)
{
if(!Stricmp(Base,FilePart(Node->ln_Name)))
{
BPTR ListLock;
if(ListLock = Lock(Node->ln_Name,ACCESS_READ))
{
if(SameLock(ListLock,NameLock) == LOCK_SAME)
{
DeleteGenericListNode(List,Node,TRUE);
Done = TRUE;
}
UnLock(ListLock);
}
}
}
UnlockGenericList(List);
UnLock(NameLock);
}
}
/* CloseXPR():
*
* Close the XPR library if it is still open.
*/
VOID
CloseXPR()
{
if(XProtocolBase)
{
XProtocolCleanup(XprIO);
CloseLibrary(XProtocolBase);
XProtocolBase = NULL;
SerWriteUpdate();
ConTransferUpdate();
SetTransferMenu(TRUE);
}
}
/* ChangeProtocol(STRPTR ProtocolName):
*
* Select a different file transfer protocol.
*/
BOOL
ChangeProtocol(STRPTR ProtocolName,LONG Type)
{
if(Type == XFER_DEFAULT)
{
ProtocolName = Config->TransferConfig->DefaultLibrary;
Type = Config->TransferConfig->DefaultType;
}
if(Type == XFER_XPR)
{
if(ProtocolName && !ProtocolName[0])
ProtocolName = NULL;
if(!ProtocolName)
ProtocolName = Config->TransferConfig->DefaultLibrary;
if(!Stricmp(ProtocolName,LastXprLibrary) && XProtocolBase)
return(TRUE);
}
/* Close the old library if still open. */
CloseXPR();
if(Type == XFER_INTERNAL)
{
UsesZModem = FALSE;
strcpy(TransferProtocolName,"ASCII");
SetTransferMenu(TRUE);
return(TRUE);
}
if(Type == XFER_EXTERNALPROGRAM)
{
CommonExternalSetup(ProtocolName);
return(TRUE);
}
return(CommonXPRSetup(ProtocolName,FALSE));
}
/* ProtocolSetup(BOOL IgnoreOptions):
*
* Set up the library and options for the external protocol.
*/
BOOL
ProtocolSetup(BOOL IgnoreOptions)
{
/* Close the old library if still open. */
CloseXPR();
if(Config->TransferConfig->DefaultType == XFER_EXTERNALPROGRAM)
{
if(Config->TransferConfig->DefaultLibrary[0])
{
CommonExternalSetup(Config->TransferConfig->DefaultLibrary);
return(TRUE);
}
else
return(FALSE);
}
return(CommonXPRSetup(LastXprLibrary,IgnoreOptions));
}